﻿// -----------------------------------------------------------------------
// <copyright company="Christoph van der Fecht - VDsoft">
// This code can be used in commercial, free and open source projects.
// </copyright>
// -----------------------------------------------------------------------
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;

namespace VDsoft.SeriesNewsReader.ViewModel
{
	/// <summary>
	/// ViewModel for all options.
	/// </summary>
	public class OptionsViewModel : ViewModelBase
	{
		/// <summary>
		/// The ToAdd.
		/// </summary>
		private string toAdd = string.Empty;

		/// <summary>
		/// The Series.
		/// </summary>
		private ObservableCollection<string> series = new ObservableCollection<string>();

		/// <summary>
		/// Command to add a new series.
		/// </summary>
		private RelayCommand addNewSeriesCommand = null;

		/// <summary>
		/// Command to remove a series from the collection.
		/// </summary>
		private RelayCommand<string> removeSeriesCommand = null;

        /// <summary>
        /// Command to import the filers by the series.
        /// </summary>
        private RelayCommand importSeriesCommand = null;

		/// <summary>
		/// Initializes a new instance of the <see cref="OptionsViewModel"/> class.
		/// </summary>
		public OptionsViewModel()
		{
			if (this.IsInDesignMode)
			{
				List<string> dummySeries = new List<string>()
				{
					"The Big Bang Theory",
					"Arrow",
					"2 Broke Girls",
					"Crisis",
					"Whitney und Alex, sex ohne ehe",
                    "Aesthetica of a Rogue Hero Special"
				};

				this.Series = new ObservableCollection<string>(dummySeries);
			}
			else
			{
				this.LoadSettings();
			}
		}

		/// <summary>
		/// Gets or sets the Series.
		/// </summary>
		public ObservableCollection<string> Series
		{
			get
			{
				return this.series;
			}

			set
			{
				if (value == this.series)
				{
					return;
				}

				this.series = value;
				this.RaisePropertyChanged("Series");
			}
		}

		/// <summary>
		/// Gets or sets the ToAdd.
		/// </summary>
		public string ToAdd
		{
			get
			{
				return this.toAdd;
			}

			set
			{
				if (value == this.toAdd)
				{
					return;
				}

				this.toAdd = value;
				this.RaisePropertyChanged("ToAdd");
			}
		}

		/// <summary>
		/// Gets the command to add a new series to the collection.
		/// </summary>
		public RelayCommand AddNewSeriesCommand
		{
			get
			{
				if (this.addNewSeriesCommand == null)
				{
					this.addNewSeriesCommand = new RelayCommand(this.AddNewSeries);
				}

				return this.addNewSeriesCommand;
			}
		}

		/// <summary>
		/// Gets the command to remove a series from the collection.
		/// </summary>
		public RelayCommand<string> RemoveSeriesCommand
		{
			get
			{
				if (this.removeSeriesCommand == null)
				{
					this.removeSeriesCommand = new RelayCommand<string>(this.RemoveSeries);
				}

				return this.removeSeriesCommand;
			}
		}

        /// <summary>
        /// Gets the command to import all filters by the series.
        /// </summary>
        public RelayCommand ImportSeriesComand
        {
            get
            {
                if (this.importSeriesCommand == null)
                {
                    this.importSeriesCommand = new RelayCommand(this.ImportSeries);
                }

                return this.importSeriesCommand;
            }
        }

		/// <summary>
		/// Saves all changes.
		/// </summary>
		public void SaveChanges()
		{
			string content = JsonConvert.SerializeObject(this.series.ToList());
			Properties.Settings.Default.Series = content;
			Properties.Settings.Default.Save();
		}

		/// <summary>
		/// Loads all settings.
		/// </summary>
		public void LoadSettings()
		{
			List<string> loaded = JsonConvert.DeserializeObject<List<string>>(Properties.Settings.Default.Series);

			if (loaded != null)
			{
				this.Series = new ObservableCollection<string>(loaded);
			}
		}

		/// <summary>
		/// Adds a new series to the collection.
		/// </summary>
		/// <param name="toAdd">Series name to add.</param>
		private void AddNewSeries()
		{
			if (string.IsNullOrEmpty(this.toAdd))
			{
				return;
			}

			this.series.Add(toAdd);
			this.Series = new ObservableCollection<string>(this.series.OrderBy(x => x).ToList());
			this.ToAdd = string.Empty;
		}

		/// <summary>
		/// Removes a seres from the collection.
		/// </summary>
		/// <param name="toRemove">Series to remove.</param>
		private void RemoveSeries(string toRemove)
		{
			if (string.IsNullOrEmpty(toRemove) || !this.Series.Contains(toRemove))
			{
				return;
			}

			this.series.Remove(toRemove);
			this.Series = new ObservableCollection<string>(this.series.OrderBy(x => x).ToList());
		}
        
        /// <summary>
        /// Imports the filters by the series.
        /// </summary>
        private void ImportSeries()
        {
            string warningMessage = "Series news reader try’s to determine your series through your library. This functions needs two preconditions:\n   - Your library must contain a folder for each series.\n   - The name of a folder is equal to the name of the series.\nDoes your library meet this requirements?";

            if (System.Windows.MessageBox.Show(warningMessage, "Import requirements", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                FolderBrowserDialog dialog = new FolderBrowserDialog();

                if (dialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                DirectoryInfo dir = new DirectoryInfo(dialog.SelectedPath);

                foreach (DirectoryInfo current in dir.GetDirectories())
                {
                    this.Series.Add(current.Name);
                }
            }

            return;
        }
	}
}
